from ..extensions import marshmallow as ma
from marshmallow import fields


class ErrorSchema(ma.Schema):
    code = fields.Int()
    message = fields.Str()
    success = fields.Bool()

    def __init__(self, code, message):
        ma.Schema.__init__(self)
        self.code = code
        self.message = message

    def jsonify(self):
        rv  =  super().jsonify({
            'code': self.code,
            'message': self.message,
            'success': False
        })

        return rv  , 400

    def to_map(self, *args, **kwargs):
        return super().dump({
            'code': self.code,
            'message': self.message
        }, *args, **kwargs).data

def _error_handler(errors, data):
    print(errors, data)


class ParamError(ma.Schema):
    code = fields.Str()
    message = fields.Str()
    success = fields.Bool()
    errors = fields.Dict()

    def __init__(self, errors):
        ma.Schema.__init__(self)
        self._errors = {}
        for param, error in errors.items():
            if error is not isinstance(list, tuple):
                error = [error]
            self._errors[param] = error

    @classmethod
    def create(cls, key, error):
        return ParamError({
            key: error
        })

    def jsonify(self):
        return super().jsonify({
            'code': 900000,
            'message': '参数错误',
            'errors': self._errors,
            'success': False
        })


class Error(ma.Schema):
    class Meta:
        fields = ('code', 'message', 'errors', 'success')


class NoParamError(Error):
    def jsonify(self):
        return super().jsonify(
            {'code': 9000001, 'message': '无请求参数', 'errors': None, 'success': False}), 400


class ServerError(Error):
    def jsonify(self):
        return super().jsonify({
            'code': 900000,
            'message': '服务器错误',
            'success': False,
            'errors': None
        }), 500


class NewParamError(Error):
    errors = fields.Dict()

    def jsonify(self, errors):
        return super().jsonify(
            {
                'code': 9000002,
                'message': '参数错误',
                'success': False,
                'errors': errors
            }
        ), 400


class ClientError(ma.Schema):
    code = fields.Int()
    message = fields.Str()
    success = fields.Bool()

    def __init__(self, code, message):
        ma.Schema.__init__(self)
        self.code = code
        self.message = message

    def jsonify(self):
        return super().jsonify({
            'code': self.code,
            'message': self.message,
            'success': False
        }), 400

class ParamErrorSchema(ma.Schema):
    def __init__(self):
        ma.Schema.__init__(self)

    code = fields.Str()
    message = fields.Str()
    success = fields.Bool()

    def jsonify(self, error):
        error_list = []
        messages = error.messages

        def find_field_help_text(field_name):
            for field in error.fields:
                if field.name == field_name:
                    return field.metadata.get('help_text', None)

        for k, v in messages.items():
            if isinstance(v, (list, tuple)):
                param_error_list = []
                field_name = find_field_help_text(k) or k
                for e in v:
                    param_error_list.append(field_name + e)
                error_list.append(''.join(param_error_list))
        return super().jsonify(
            {
                'code': 900000,
                'message': ','.join(error_list),
                'success': False
            }
        )

    class Meta:
        error_handler = _error_handler
        fields = ('code', 'message', 'success')


LOCAL_AUTH_NOT_EXIST = ParamError.create('login_name', '用户不存在')
LOGIN_NAME_EXIST = ParamError.create('login_name', '登陆名已经存在')
INCORRECT_PASSWORD =  ParamError.create('password', '密码不正确')

PARAMS_DOES_NOT_EXIST = ErrorSchema(900001, '参数不存在')
AUTH_NOT_EXIST = ErrorSchema(900002,'没有权限')
PARAMS_ERROR = ParamErrorSchema()

PRODUCT_NOT_EXIST = ErrorSchema(100000, '产品不存在或已下架')
STOCK_NOT_EXIST = ErrorSchema(300000,'报价不存在')
SERVICE_NOT_EXIST = ErrorSchema(400000,'服务项不存在')

SHOP_CART_NOT_EXIST = ErrorSchema(500000, '购物车不存在')
SHOP_CART_HAS_OWNER = ErrorSchema(500001, '购物车已被认领')
SHOP_CART_STATUS_ERROR = ErrorSchema(500002, '购物车已被删除')

CART_ITEM_NOT_EXIST = ErrorSchema(510000, '购物车条目不存在')
CART_ITEM_STATUS_ERROR = ErrorSchema(520000, '购物车条目状态不正确')
CART_ITEM_HAS_OWNER = ErrorSchema(530000,'购物车条目已属于其它会员')
CART_ITEM_NOT_BELONG_SHOP_CART = ErrorSchema(5300004, '购物车条目不必于当前购物车')
FUND_CHANNEL_NOT_EXIST = ErrorSchema(600001,'资金渠道不存在')
MEMBER_NOT_EXIST = ParamError.create('member', '会员不存在或已冻结')
CURRENCY_NOT_EXIST = ErrorSchema(100001, '币种不存在')

NO_PARAM_ERROR = NoParamError()
NEW_PARAM_ERROR = NewParamError()
SERVER_ERROR = ServerError()
